package com.gyy.Alarm;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.gyy.Thermometry.JpegWithAppendData;
import com.gyy.sdk.HCNetSDK;
import com.sun.jna.Pointer;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.gyy.Application.hCNetSDK;
import static com.gyy.Application.userId;

/**
 * @Author Qiu Jiahang
 * @Date 2021/4/6 19:23
 */
public class FMSGCallBack_V31 implements HCNetSDK.FMSGCallBack_V31 {

    private JpegWithAppendData jpegWithAppendData = new JpegWithAppendData();

    private Object lock = new Object();
    /**
     * 保存温度信息
     */
    private Map tempMap = new HashMap(4);

    @Override
    public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        List<String[]> list = AlarmDataHandle(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser);
        /*for(int i=0; i<list.size(); i++){
            System.out.println(list.get(i).toString());
        }*/
        return true;
    }

    public List<String[]> AlarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        // alarmList 为报警信息集合
        List<String[]> alarmList = new ArrayList<>();

        System.out.println("报警事件发生，进入回调");
        String hexString = Integer.toHexString(lCommand);
        System.out.println("报警类型 = 0x" + hexString);
        String sAlarmType;

        /*System.out.println("========================== 截图");
        // 截图
        jpegWithAppendData.getCameraJpeg(userId, 2);*/


        String[] newRow = new String[3];
        //报警时间
        Date today = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String[] sIP;
        sAlarmType = new String("lCommand=") + lCommand;
        switch (lCommand) {
            //火点检测报警
            case HCNetSDK.COMM_FIREDETECTION_ALARM:
                HCNetSDK.NET_DVR_FIREDETECTION_ALARM struFireDetection = new HCNetSDK.NET_DVR_FIREDETECTION_ALARM();
                struFireDetection.write();
                Pointer fireDetectionPointer = struFireDetection.getPointer();
                fireDetectionPointer.write(0, pAlarmInfo.getByteArray(0, struFireDetection.size()), 0, struFireDetection.size());
                struFireDetection.read();
                System.out.println("火点检测报警: RelativeTime: " + struFireDetection.dwRelativeTime
                        + ", AbsTime:" + struFireDetection.dwAbsTime
                        + ", PTZ{ PanPos:" + struFireDetection.wPanPos + ", TiltPos:" + struFireDetection.wTiltPos + ", ZoomPos:" + struFireDetection.wZoomPos + " }"
                        + ", PicDataLen:" + struFireDetection.dwPicDataLen
                        + ", DevInfo{ DevIP:" + struFireDetection.struDevInfo.struDevIP.toString() + ", Port:" + struFireDetection.struDevInfo.wPort + ", Channel:" + struFireDetection.struDevInfo.byChannel + ", IvmsChannel:" + struFireDetection.struDevInfo.byIvmsChannel + "}"
                        + ", FireMaxTemperature:" + struFireDetection.wFireMaxTemperature
                        + ", TargetDistance:" + struFireDetection.wTargetDistance
                        + ", fireRectInfo{ fX:" + struFireDetection.struRect.fX
                        + ", fY:" + struFireDetection.struRect.fY
                        + ", fWidth:" + struFireDetection.struRect.fWidth
                        + ", fHeight:" + struFireDetection.struRect.fHeight + "}"
                        + ", fireMaxTemperaturePoint{ fX:" + struFireDetection.struPoint.fX + ", fY:" + struFireDetection.struPoint.fY + "}");
                HCNetSDK.NET_DVR_TIME struAbsTime = new HCNetSDK.NET_DVR_TIME();
                struAbsTime.write();
                struAbsTime.dwYear = (struFireDetection.dwAbsTime >> 26) + 2000;
                struAbsTime.dwMonth = (struFireDetection.dwAbsTime >> 22) & 15;
                struAbsTime.dwDay = (struFireDetection.dwAbsTime >> 17) & 31;
                struAbsTime.dwHour = (struFireDetection.dwAbsTime >> 12) & 31;
                struAbsTime.dwMinute = (struFireDetection.dwAbsTime >> 6) & 63;
                struAbsTime.dwSecond = (struFireDetection.dwAbsTime >> 0) & 63;
                struAbsTime.read();
                //保存报警抓拍图片
                if (struFireDetection.dwPicDataLen > 0 && struFireDetection.pBuffer != null) {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss");
                    String newName = sf.format(new Date());
                    FileOutputStream fout;
                    try {
                        String filename = ".\\pic\\FireDetectionPic[" + new String(pAlarmer.sDeviceIP).trim() + "_" + newName + "].jpg";
                        fout = new FileOutputStream(filename);
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = struFireDetection.pBuffer.getByteBuffer(offset, struFireDetection.dwPicDataLen);
                        byte[] bytes = new byte[struFireDetection.dwPicDataLen];
                        buffers.rewind();
                        buffers.get(bytes);
                        fout.write(bytes);
                        fout.close();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                newRow[0] = struAbsTime.toStringTime();
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);
                break;
            //移动侦测、视频丢失、遮挡、IO信号量等报警信息，报警数据为可变长
            case HCNetSDK.COMM_ALARM_V40:
                HCNetSDK.NET_DVR_ALARMINFO_V40 struAlarmInfoV40 = new HCNetSDK.NET_DVR_ALARMINFO_V40();
                struAlarmInfoV40.write();
                Pointer pInfoV40 = struAlarmInfoV40.getPointer();
                pInfoV40.write(0, pAlarmInfo.getByteArray(0, struAlarmInfoV40.size()), 0, struAlarmInfoV40.size());
                struAlarmInfoV40.read();

                switch (struAlarmInfoV40.struAlarmFixedHeader.dwAlarmType) {
                    case 0:
                        struAlarmInfoV40.struAlarmFixedHeader.ustruAlarm.setType(HCNetSDK.struIOAlarm.class);
                        struAlarmInfoV40.read();
                        sAlarmType = sAlarmType + new String("：信号量报警") + "，" + "报警输入口：" + struAlarmInfoV40.struAlarmFixedHeader.ustruAlarm.struioAlarm.dwAlarmInputNo;
                        break;
                    case 1:
                        sAlarmType = sAlarmType + new String("：硬盘满");
                        break;
                    case 2:
                        sAlarmType = sAlarmType + new String("：信号丢失");
                        break;
                    case 3:
                        struAlarmInfoV40.struAlarmFixedHeader.ustruAlarm.setType(HCNetSDK.struAlarmChannel.class);
                        struAlarmInfoV40.read();
                        int iChanNum = struAlarmInfoV40.struAlarmFixedHeader.ustruAlarm.strualarmChannel.dwAlarmChanNum;
                        sAlarmType = sAlarmType + new String("：移动侦测") + "，" + "报警通道个数：" + iChanNum + "，" + "报警通道号：";

                        for (int i = 0; i < iChanNum; i++) {
                            byte[] byChannel = struAlarmInfoV40.pAlarmData.getByteArray(i * 4, 4);

                            int iChanneNo = 0;
                            for (int j = 0; j < 4; j++) {
                                int ioffset = j * 8;
                                int iByte = byChannel[j] & 0xff;
                                iChanneNo = iChanneNo + (iByte << ioffset);
                            }

                            sAlarmType = sAlarmType + "+ch[" + iChanneNo + "]";
                        }

                        break;
                    case 4:
                        sAlarmType = sAlarmType + new String("：硬盘未格式化");
                        break;
                    case 5:
                        sAlarmType = sAlarmType + new String("：读写硬盘出错");
                        break;
                    case 6:
                        sAlarmType = sAlarmType + new String("：遮挡报警");
                        break;
                    case 7:
                        sAlarmType = sAlarmType + new String("：制式不匹配");
                        break;
                    case 8:
                        sAlarmType = sAlarmType + new String("：非法访问");
                        break;
                }

                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);
                break;

            // 9000报警信息
            case HCNetSDK.COMM_ALARM_V30:
                HCNetSDK.NET_DVR_ALARMINFO_V30 strAlarmInfoV30 = new HCNetSDK.NET_DVR_ALARMINFO_V30();
                strAlarmInfoV30.write();
                Pointer pInfoV30 = strAlarmInfoV30.getPointer();
                pInfoV30.write(0, pAlarmInfo.getByteArray(0, strAlarmInfoV30.size()), 0, strAlarmInfoV30.size());
                strAlarmInfoV30.read();
                switch (strAlarmInfoV30.dwAlarmType) {
                    case 0:
                        sAlarmType = sAlarmType + new String("：信号量报警") + "，" + "报警输入口：" + (strAlarmInfoV30.dwAlarmInputNumber + 1);
                        break;
                    case 1:
                        sAlarmType = sAlarmType + new String("：硬盘满");
                        break;
                    case 2:
                        sAlarmType = sAlarmType + new String("：信号丢失");
                        break;
                    case 3:
                        sAlarmType = sAlarmType + new String("：移动侦测") + "，" + "报警通道：";
                        for (int i = 0; i < 64; i++) {
                            if (strAlarmInfoV30.byChannel[i] == 1) {
                                sAlarmType = sAlarmType + "ch" + (i + 1) + " ";
                            }
                        }
                        break;
                    case 4:
                        sAlarmType = sAlarmType + new String("：硬盘未格式化");
                        break;
                    case 5:
                        sAlarmType = sAlarmType + new String("：读写硬盘出错");
                        break;
                    case 6:
                        sAlarmType = sAlarmType + new String("：遮挡报警");
                        break;
                    case 7:
                        sAlarmType = sAlarmType + new String("：制式不匹配");
                        break;
                    case 8:
                        sAlarmType = sAlarmType + new String("：非法访问");
                        break;
                }
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);
                break;
            // 行为分析信息上传
            case HCNetSDK.COMM_ALARM_RULE:
                HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm = new HCNetSDK.NET_VCA_RULE_ALARM();
                strVcaAlarm.write();
                Pointer pVcaInfo = strVcaAlarm.getPointer();
                pVcaInfo.write(0, pAlarmInfo.getByteArray(0, strVcaAlarm.size()), 0, strVcaAlarm.size());
                strVcaAlarm.read();

                switch (strVcaAlarm.struRuleInfo.wEventTypeEx) {
                    case 1:
                        sAlarmType = sAlarmType + new String("：穿越警戒面") + "，" +
                                "_wPort:" + strVcaAlarm.struDevInfo.wPort +
                                "_byChannel:" + strVcaAlarm.struDevInfo.byChannel +
                                "_byIvmsChannel:" + strVcaAlarm.struDevInfo.byIvmsChannel +
                                "_Dev IP：" + new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4);
                        break;
                    case 2:
                        sAlarmType = sAlarmType + new String("：目标进入区域") + "，" +
                                "_wPort:" + strVcaAlarm.struDevInfo.wPort +
                                "_byChannel:" + strVcaAlarm.struDevInfo.byChannel +
                                "_byIvmsChannel:" + strVcaAlarm.struDevInfo.byIvmsChannel +
                                "_Dev IP：" + new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4);
                        break;
                    case 3:
                        sAlarmType = sAlarmType + new String("：目标离开区域") + "，" +
                                "_wPort:" + strVcaAlarm.struDevInfo.wPort +
                                "_byChannel:" + strVcaAlarm.struDevInfo.byChannel +
                                "_byIvmsChannel:" + strVcaAlarm.struDevInfo.byIvmsChannel +
                                "_Dev IP：" + new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4);
                        break;
                    default:
                        sAlarmType = sAlarmType + new String("：其他行为分析报警，事件类型：")
                                + strVcaAlarm.struRuleInfo.wEventTypeEx +
                                "_wPort:" + strVcaAlarm.struDevInfo.wPort +
                                "_byChannel:" + strVcaAlarm.struDevInfo.byChannel +
                                "_byIvmsChannel:" + strVcaAlarm.struDevInfo.byIvmsChannel +
                                "_Dev IP：" + new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4);
                        break;
                }
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);

                if (strVcaAlarm.dwPicDataLen > 0) {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String newName = sf.format(new Date());
                    FileOutputStream fout;
                    try {
                        fout = new FileOutputStream(".\\pic\\" + new String(pAlarmer.sDeviceIP).trim()
                                + "wEventTypeEx[" + strVcaAlarm.struRuleInfo.wEventTypeEx + "]_" + newName + "_vca.jpg");
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = strVcaAlarm.pImage.getByteBuffer(offset, strVcaAlarm.dwPicDataLen);
                        byte[] bytes = new byte[strVcaAlarm.dwPicDataLen];
                        buffers.rewind();
                        buffers.get(bytes);
                        fout.write(bytes);
                        fout.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;
            //ISAPI协议报警信息
            case HCNetSDK.COMM_ISAPI_ALARM:
                HCNetSDK.NET_DVR_ALARM_ISAPI_INFO struEventISAPI = new HCNetSDK.NET_DVR_ALARM_ISAPI_INFO();
                struEventISAPI.write();
                Pointer pEventISAPI = struEventISAPI.getPointer();
                pEventISAPI.write(0, pAlarmInfo.getByteArray(0, struEventISAPI.size()), 0, struEventISAPI.size());
                struEventISAPI.read();

                sAlarmType = sAlarmType + "：ISAPI协议报警信息, 数据格式:" + struEventISAPI.byDataType +
                        ", 图片个数:" + struEventISAPI.byPicturesNumber;

                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);

                SimpleDateFormat sf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String curTime = sf1.format(new Date());
                FileOutputStream foutdata;
                try {
                    String jsonfilename = ".\\pic\\" + new String(pAlarmer.sDeviceIP).trim() + curTime + "_ISAPI_Alarm_" + ".json";
                    foutdata = new FileOutputStream(jsonfilename);
                    //将字节写入文件
                    ByteBuffer jsonbuffers = struEventISAPI.pAlarmData.getByteBuffer(0, struEventISAPI.dwAlarmDataLen);
                    byte[] jsonbytes = new byte[struEventISAPI.dwAlarmDataLen];
                    jsonbuffers.rewind();
                    jsonbuffers.get(jsonbytes);
                    foutdata.write(jsonbytes);
                    foutdata.close();
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                for (int i = 0; i < struEventISAPI.byPicturesNumber; i++) {
                    HCNetSDK.NET_DVR_ALARM_ISAPI_PICDATA struPicData = new HCNetSDK.NET_DVR_ALARM_ISAPI_PICDATA();
                    struPicData.write();
                    Pointer pPicData = struPicData.getPointer();
                    pPicData.write(0, struEventISAPI.pPicPackData.getByteArray(i * struPicData.size(), struPicData.size()), 0, struPicData.size());
                    struPicData.read();

                    FileOutputStream fout;
                    try {
                        String filename = ".\\pic\\" + new String(pAlarmer.sDeviceIP).trim() + curTime +
                                "_ISAPIPic_" + i + "_" + new String(struPicData.szFilename).trim() + ".jpg";
                        fout = new FileOutputStream(filename);
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = struPicData.pPicData.getByteBuffer(offset, struPicData.dwPicLen);
                        byte[] bytes = new byte[struPicData.dwPicLen];
                        buffers.rewind();
                        buffers.get(bytes);
                        fout.write(bytes);
                        fout.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;

            case HCNetSDK.COMM_THERMOMETRY_ALARM:
                temperatureAlarm();
                break;


            default:
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);
                break;
        }
        return alarmList;
    }

    /**
     * 温度报警
     */
    private void temperatureAlarm() {
        System.out.println("===================== 温度告警");

        System.out.println("===================== 获取温度信息");
        // 获取温度信息
        getThermometryData(userId, 2, (byte) 0, (byte) 1, (short) 1);

        System.out.println("========================== 截图");
        // 截图
        String imgBase = getCameraJpegTwo(userId, 2);

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (lock) {
            tempMap.put("imgBase", imgBase);
            System.out.println(tempMap.toString());

            String result = HttpUtil.post("/url/insertUser", tempMap);
            JSONObject data = JSONObject.parseObject(result);
            if (data.getInteger("code") == 0) {
                System.out.println("============== 数据传输成功");

            } else {

                System.out.println("============== 再尝试传输一次");
                String result2 = HttpUtil.post("/url/insertUser", tempMap);
                JSONObject data2 = JSONObject.parseObject(result2);
                if (data2.getInteger("code") == 0) {
                    System.out.println("============== 再次数据传输成功");
                } else {
                    System.out.println("============== 再次数据传输失败");
                }

            }

            tempMap.clear();
        }

    }

    private void getThermometryData(int lUserID, int iChannelNum, byte RuleID, byte Mode, short Interval) {
        long lHandle;
        HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND m_strRealtimeThermometryCond = new HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND();
        m_strRealtimeThermometryCond.dwSize = m_strRealtimeThermometryCond.size();
        m_strRealtimeThermometryCond.dwChan = iChannelNum;
        m_strRealtimeThermometryCond.byRuleID = RuleID;//规则ID，0代表获取全部规则，具体规则ID从1开始
        m_strRealtimeThermometryCond.byMode = Mode;//长连接模式：0-保留；1-定时模式；2-温差模式
        m_strRealtimeThermometryCond.wInterval = Interval;//上传间隔（仅温差模式支持），取值范围：1-3600 秒，填0则默认3600S上传一次

        FRemoteConfigCallback fRemoteConfigCallback = new FRemoteConfigCallback();
        Pointer pUserData = null;
        m_strRealtimeThermometryCond.write();

        lHandle = hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_GET_REALTIME_THERMOMETRY, m_strRealtimeThermometryCond.getPointer(), m_strRealtimeThermometryCond.dwSize, fRemoteConfigCallback, pUserData);
        if (lHandle < 0) {
            System.out.println("建立实时测温规则获取长连接失败，错误号：" + hCNetSDK.NET_DVR_GetLastError());
            return;
        }
        System.out.println("建立实时测温规则获取长连接成功!");
        /*try {
            // 只要程序没结束，实时温度数据就会一直上传
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/
    }

    private class FRemoteConfigCallback implements HCNetSDK.FRemoteConfigCallBack {

        //状态回调函数
        public void invoke(int dwType, Pointer lpBuffer, int dwBufferLen, Pointer pUserData) {
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String newName = sf.format(new Date());
            System.out.println("长连接回调获取数据类型:" + dwType);
            switch (dwType) {
                case 0://NET_SDK_CALLBACK_TYPE_STATUS
                    HCNetSDK.REMOTECONFIGSTATUS_THERMOMETRY struCfgStatus = new HCNetSDK.REMOTECONFIGSTATUS_THERMOMETRY();
                    struCfgStatus.write();
                    Pointer pCfgStatus = struCfgStatus.getPointer();
                    pCfgStatus.write(0, lpBuffer.getByteArray(0, struCfgStatus.size()), 0, struCfgStatus.size());
                    struCfgStatus.read();
                    int iStatus = 0;
                    for (int i = 0; i < 4; i++) {
                        int ioffset = i * 8;
                        int iByte = struCfgStatus.byStatus[i] & 0xff;
                        iStatus = iStatus + (iByte << ioffset);
                    }

                    switch (iStatus) {
                        case 1000:// NET_SDK_CALLBACK_STATUS_SUCCESS
                            System.out.println("手动测温实时获取成功,dwStatus:" + iStatus);
                            break;
                        case 1001:
                            System.out.println("正在实时获取手动测温,dwStatus:" + iStatus);
                            break;
                        case 1002:
                            int iErrorCode = 0;
                            for (int i = struCfgStatus.size() - 3; i <= struCfgStatus.size(); i++) {
                                int ioffset = i * 8;
                                int iByte = struCfgStatus.byErrorCode[i] & 0xff;
                                iErrorCode = iErrorCode + (iByte << ioffset);
                            }
                            System.out.println("手动测温实时获取失败, dwStatus:" + iStatus + "错误号:" + iErrorCode);
                            break;
                    }
                    break;
                case 2://NET_SDK_CALLBACK_TYPE_DATA
                    HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD m_struThermometryUpload = new HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD();
                    m_struThermometryUpload.write();
                    Pointer pmt = m_struThermometryUpload.getPointer();
                    pmt.write(0, lpBuffer.getByteArray(0, m_struThermometryUpload.size()), 0, m_struThermometryUpload.size());
                    m_struThermometryUpload.read();

                    try {
                        synchronized (lock) {
                            tempMap.clear();
                        }
                        String strTemp = "";
                        if (m_struThermometryUpload.byRuleCalibType == 0) {   //规则标定类型：0- 点
                            strTemp = "规则ID：" + m_struThermometryUpload.byRuleID
                                    + "，规则名称：" + new String(m_struThermometryUpload.szRuleName, "GBK").trim()
                                    + "，规则类型：" + m_struThermometryUpload.byRuleCalibType
                                    + "，预置点号：" + m_struThermometryUpload.wPresetNo
                                    + "，点温度：" + m_struThermometryUpload.struPointThermCfg.fTemperature
                                    + "，点坐标：(" + m_struThermometryUpload.struPointThermCfg.struPoint.fX + "," + m_struThermometryUpload.struPointThermCfg.struPoint.fY + ")"
                                    + "\n";
                            synchronized (lock) {
                                tempMap.put("high", m_struThermometryUpload.struPointThermCfg.fTemperature);
                                tempMap.put("desc", strTemp);
                            }

                        } else if (m_struThermometryUpload.byRuleCalibType == 1) {   //规则标定类型：1- 框
                            strTemp = "规则ID：" + m_struThermometryUpload.byRuleID
                                    + "，规则名称：" + new String(m_struThermometryUpload.szRuleName, "GBK").trim()
                                    + "，规则类型：" + m_struThermometryUpload.byRuleCalibType
                                    + "，预置点号：" + m_struThermometryUpload.wPresetNo
                                    + "，区域最高温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fMaxTemperature
                                    + "，区域最低温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fMinTemperature
                                    + "，区域平均温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fAverageTemperature
                                    + "，区域温差：" + m_struThermometryUpload.struLinePolygonThermCfg.fTemperatureDiff
                                    + "，有效点数：" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.dwPointNum
                                    + "，区域边界点坐标：";
                            String temp = "";
                            for (int ij = 0; ij < m_struThermometryUpload.struLinePolygonThermCfg.struRegion.dwPointNum; ij++) {
                                temp = temp + ij + "-(" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[ij].fX + "," + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[ij].fY + ")、";
                            }

                            synchronized (lock) {
                                tempMap.put("high", m_struThermometryUpload.struLinePolygonThermCfg.fMaxTemperature);
                                tempMap.put("desc", strTemp);
                            }

                        } else if (m_struThermometryUpload.byRuleCalibType == 2) {   //规则标定类型：2- 线
                            strTemp = "规则ID：" + m_struThermometryUpload.byRuleID
                                    + "，规则名称：" + new String(m_struThermometryUpload.szRuleName, "GBK").trim()
                                    + "，规则类型：" + m_struThermometryUpload.byRuleCalibType
                                    + "，预置点号：" + m_struThermometryUpload.wPresetNo
                                    + "，线最高温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fMaxTemperature
                                    + "，线最低温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fMinTemperature
                                    + "，线平均温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fAverageTemperature
                                    + "，线温差：" + m_struThermometryUpload.struLinePolygonThermCfg.fTemperatureDiff
                                    + "，有效点数：" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.dwPointNum
                                    + "，线端点坐标：0-(" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[0].fX + "," + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[0].fY + ")"
                                    + "、1-(" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[1].fX + "," + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[1].fY + ")"
                                    + "\n";

                            synchronized (lock) {
                                tempMap.put("high", m_struThermometryUpload.struLinePolygonThermCfg.fMaxTemperature);
                                tempMap.put("desc", strTemp);
                            }
                        }

                    } catch (IOException e) {
                        System.out.println("异常");
                    }

            }
        }

    }


    private String getCameraJpegTwo(int lUserID, int iChannelNum) {
        boolean bRet;
        HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppendData = new HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA();
        m_strJpegWithAppendData.dwSize = m_strJpegWithAppendData.size();
        HCNetSDK.BYTE_ARRAY ptrJpegByte = new HCNetSDK.BYTE_ARRAY(8 * 1024 * 1024);
        HCNetSDK.BYTE_ARRAY ptrP2PDataByte = new HCNetSDK.BYTE_ARRAY(4 * 1024 * 1024);
        m_strJpegWithAppendData.pJpegPicBuff = ptrJpegByte.getPointer();
        m_strJpegWithAppendData.pP2PDataBuff = ptrP2PDataByte.getPointer();
        m_strJpegWithAppendData.dwJpegPicLen = 8 * 1024 * 1024;
        m_strJpegWithAppendData.dwP2PDataLen = 4 * 1024 * 1024;

        m_strJpegWithAppendData.write();
        bRet = hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID, iChannelNum, m_strJpegWithAppendData);

        if (bRet == true) {
            //测温图片
            if (m_strJpegWithAppendData.dwJpegPicLen > 0) {

                try {
                    ByteBuffer buffers = m_strJpegWithAppendData.pJpegPicBuff.getByteBuffer(0, m_strJpegWithAppendData.dwJpegPicLen);
                    String imgBase = getString(Base64.getEncoder().encode(buffers));
                    return "data:image/jpeg;base64," + imgBase;

                } catch (Exception e) {
                    System.out.println("异常");
                }
            }
        } else {
            System.out.println("抓图失败，错误码" + hCNetSDK.NET_DVR_GetLastError());
        }
        return null;
    }

    /**
     * ByteBuffer 转换 String
     *
     * @param buffer
     * @return
     */
    private String getString(ByteBuffer buffer) {
        Charset charset = null;
        CharsetDecoder decoder = null;
        CharBuffer charBuffer = null;
        try {
            charset = Charset.forName("UTF-8");
            decoder = charset.newDecoder();
            charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
            return charBuffer.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }

}
